import 'dart:convert';
import 'dart:io';

import 'package:coin_genarate/coin_generate.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/foundation.dart';
import 'package:wallet_home/tools/aes_util.dart';
import 'package:wallet_home/tools/common.dart';

import '../model/wallet_list_model.dart';

typedef CoinListCallback = void Function(List<CoinsBean> coins); //

class CoinManager {
  static CoinManager _manager = CoinManager._();

  CoinManager._();

  factory CoinManager() => _manager;

  List<CoinsBean> _allCoinList = <CoinsBean>[];

  List<CoinsBean> _allSelectedCoinList = <CoinsBean>[];

  List<CoinsBean> get allCoinList {
    return _allCoinList;
  }

  List<CoinsBean> get allSelectedCoinList {
    return _allSelectedCoinList;
  }

  CoinListCallback callback;

  static List<String> mnemonicList = [
    "science menu teach digital dolphin nice cable design museum gym method race",
    "pistol enable morning fan oppose aerobic check dad soda awesome prefer option",
    "violin minor nurse fresh broccoli dignity together spirit pistol either auction neck",
    "vendor shy tennis canyon section fashion chalk general crunch very panel goddess",
    "good east sell harsh cake bounce bicycle please coral enlist anchor heart",
    "nose grace cheap upon owner naive risk device spread winter refuse cost",
    "payment fatal boat photo symptom dog rocket gospel foot box sell praise"
  ];

  void setCoinListListener(CoinListCallback coinListCallback) {
    this.callback = coinListCallback;
  }

  /// 数组入参
  static List<GenCoin> getGenCoinList() {
    List<GenCoin> genCoinList = List();
    genCoinList.add(GenCoin(name: "BTC", path: "m/44'/0'/0'/0/0"));
    genCoinList.add(GenCoin(name: "ETH", path: "m/44'/60'/0'/0/0"));
    // genCoinList.add(GenCoin(name: "EOS", path: "m/44'/194'/0'/0/0"));
    genCoinList.add(GenCoin(name: "ELF", path: "m/44'/1616'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "CMT", path: "m/44'/302'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "BHP", path: "m/44'/547'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "BTT", path: "m/44'/34952'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "CITY", path: "m/44'/1926'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "GAME", path: "m/44'/101'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "HASH", path: "m/44'/505'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "ICX", path: "m/44'/74'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "NAS", path: "m/44'/2718'/0'/0/0"));
    genCoinList.add(GenCoin(name: "TRX", path: "m/44'/195'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "THETA", path: "m/44'/500'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "XPC", path: "m/44'/398'/0'/0/0"));
//    genCoinList.add(GenCoin(name: "BTM", path: "m/44'/153'/0'/0/0"));
    return genCoinList;
  }

  ///获取SDK方的数据
  Future<List<Coin>> getOriginAllData(List<GenCoin> genCoinList) async {
    String mnemonic = AESUtil.decryptString(SpUtil.getString("mnemonic_list"));
    List<GenCoin> genCoinList = getGenCoinList();
    Map<String, dynamic> param = {'mnemonic':mnemonic,'coinNames':genCoinList};
    /// compute创建异步线程生成币种
    List<Coin> coins = await compute(getCoins,param);
    return Future.value(coins);
  }

  static Future<List<Coin>> getCoins(Map<String, dynamic> data) async{
    final manager = CoinGenerateManager();
    return await manager.generateCoinList(data['mnemonic'], data['coinNames']);
  }
  /// 处理币种数据
  void handleListCoinData(List<Coin> list) {
      print('isolate Data：$list');
      list.forEach((coin) {
        CoinsBean bean = CoinsBean();
        bean.title = coin.name;
        bean.address = coin.addr;
        bean.privateKey = coin.privateKey;
        bean.publicKey = coin.publicKey;
        switch (coin.name) {
          case "BTC":
            bean.isSelected = true;
            bean.coinid = "Bitcoin";
            bean.img =
            "assets/images/btc_icon.png";
            bean.num = "8.00000000";
            bean.cnyBalance = "93682.16";
            bean.cnyMoney = "749457.28";
            break;
          case "ETH":
            bean.isSelected = false;
            bean.coinid = "Ether";
            bean.img =
            "assets/images/eth_icon.png";
            bean.num = "3.02000000";
            bean.cnyBalance = "2602.42";
            bean.cnyMoney = "7859.3084";
            break;
          case "EOS":
            bean.isSelected = false;
            bean.coinid = "EOS";
            bean.img =
            "assets/images/eos_icon.png";
            bean.num = "2.03250000";
            bean.cnyBalance = "250.00";
            bean.cnyMoney = "508.125";
            break;
          case "ELF":
            bean.isSelected = false;
            bean.coinid = "AELF";
            bean.img =
            "assets/images/elf_icon.png";
            bean.num = "12.03600000";
            bean.cnyBalance = "0.52";
            bean.cnyMoney = "6.25872";
            break;
          case "CMT":
            bean.isSelected = false;
            bean.coinid = "Community";
            bean.img =
            "assets/images/cmt_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "BHP":
            bean.isSelected = false;
            bean.coinid = "BHP";
            bean.img =
            "assets/images/bhp_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "BTT":
            bean.isSelected = false;
            bean.coinid = "ByteTrade";
            bean.img =
            "assets/images/btt_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "CITY":
            bean.isSelected = false;
            bean.coinid = "City Coin";
            bean.img =
            "assets/images/city_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "GAME":
            bean.isSelected = false;
            bean.coinid = "GameCredits";
            bean.img =
            "assets/images/game_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "HASH":
            bean.isSelected = false;
            bean.coinid = "Provenance";
            bean.img =
            "assets/images/hash_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "ICX":
            bean.isSelected = false;
            bean.coinid = "ICON";
            bean.img =
            "assets/images/icx_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "NAS":
            bean.isSelected = false;
            bean.coinid = "Nebulas";
            bean.img =
            "assets/images/nas_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "TRX":
            bean.isSelected = false;
            bean.coinid = "Tron";
            bean.img =
            "assets/images/trx_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.16";
            bean.cnyMoney = "0.00";
            break;
          case "THETA":
            bean.isSelected = false;
            bean.coinid = "Theta";
            bean.img =
            "assets/images/theta_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "XPC":
            bean.isSelected = false;
            bean.coinid = "XPChain";
            bean.img =
            "assets/images/xpc_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
          case "BTM":
            bean.isSelected = false;
            bean.coinid = "Bytom";
            bean.img =
            "assets/images/btm_icon.png";
            bean.num = "0.00000000";
            bean.cnyBalance = "0.00";
            bean.cnyMoney = "0.00";
            break;
        }
        _allCoinList.add(bean);
      });
      _allCoinList.forEach((coin) {
        if (coin.isSelected &&
                !_allSelectedCoinList.contains(
                        coin)) {
          _allSelectedCoinList.add(coin);
        }
      });

      String allListJson = json.encode(
              _allCoinList).toString();
      String selectListJson = json.encode(
              _allSelectedCoinList).toString();
      SpUtil.putString(Constant.allCoinListKey,
              allListJson);
      SpUtil.putString(Constant.selectCoinListKey,
              selectListJson);

      if (Platform.isAndroid) {
        SpUtil.putString("mnemonic_list",
                AESUtil.encryptString(
                        mnemonicList[0]));
      } else {
        SpUtil.putString("mnemonic_list",
                AESUtil.encryptString(
                        mnemonicList[1]));
      }

      callback(_allCoinList);
    }

  /// 生成全部数据和初始化列表数据
  Future<List<CoinsBean>> getListData() async {
    _allCoinList = <CoinsBean>[];
    _allSelectedCoinList = <CoinsBean>[];

    String allListData = SpUtil.getString(Constant.allCoinListKey);
    String selectListData = SpUtil.getString(Constant.selectCoinListKey);
    if (allListData.isEmpty || selectListData.isEmpty) {
      _allCoinList.clear();
      _allSelectedCoinList.clear();
      List<Coin> list = await getOriginAllData(getGenCoinList());
      handleListCoinData(list);
    } else {
      List allList = json.decode(allListData);
      List selectList = json.decode(selectListData);

      _allCoinList.addAll(CoinsBean.toList(allList));
      _allSelectedCoinList.addAll(CoinsBean.toList(selectList));
      callback(_allCoinList);
    }
    return _allCoinList;
  }

  removeSelectedCoin(String title) {
    print("allSelectedList======>${_allSelectedCoinList.length}=======>$title");
    // _allCoinList = getCoinList(false);
    _allSelectedCoinList.clear();
    for (CoinsBean tempCoin in _allCoinList) {
      if (tempCoin.title == title) {
        tempCoin.isSelected = false;
      } else {
        if (tempCoin.isSelected) {
          _allSelectedCoinList.add(tempCoin);
        }
      }
    }
    print("allSelectedList======>${_allSelectedCoinList.length}=======>$title");
  }

  saveSelectedCoin(String title) {
    //   _allCoinList = getCoinList(false);
    for (CoinsBean tempCoin in _allCoinList) {
      if (tempCoin.title == title) {
        if (!_allSelectedCoinList.contains(tempCoin)) {
          tempCoin.isSelected = true;
          _allSelectedCoinList.add(tempCoin);
        }
      }
    }
    print("allSelectedList======>${_allSelectedCoinList.length}=======>$title");
  }

  completeCoinSelected() {
    String allListJson = json.encode(_allCoinList).toString();
    String selectListJson = json.encode(_allSelectedCoinList).toString();
    SpUtil.putString(Constant.allCoinListKey, allListJson);
    SpUtil.putString(Constant.selectCoinListKey, selectListJson);
    print("have========list=======>$allListJson");
    print("have========list=======>$selectListJson");
  }

  /// 获取所有/已选币种列表
  List<CoinsBean> getCoinList(bool isSelect) {
    String coins = "";
    if (isSelect) {
      coins = SpUtil.getString(Constant.selectCoinListKey, defValue: "");
    } else {
      coins = SpUtil.getString(Constant.allCoinListKey, defValue: "");
    }
    print("coins========>sp=======>$coins");
    if (coins.isEmpty) return [];
    List list = json.decode(coins);
    List<CoinsBean> coinList = CoinsBean.toList(list);
    return coinList;
  }

  updateCoinDetail(String coinName, String upDown, String costCnyMoney,
      String transferType) {
    if (coinName.isEmpty || upDown.isEmpty || costCnyMoney.isEmpty) return;

    /// 更新全部数据
    List<CoinsBean> coinList = getCoinList(false);

    coinList.forEach((bean) {
      if (bean.title == coinName) {
        if (transferType == "0") {
          bean.num = (double.parse(bean.num) - double.parse(upDown)).toString();
          bean.cnyMoney =
              (double.parse(bean.cnyMoney) - double.parse(costCnyMoney))
                  .toString();
        } else {
          bean.num = (double.parse(bean.num) + double.parse(upDown)).toString();
          bean.cnyMoney =
              (double.parse(bean.cnyMoney) + double.parse(costCnyMoney))
                  .toString();
        }
      }
    });

    /// 更新选中列表的数据
    List<CoinsBean> coinSelectList = getCoinList(true);
    coinSelectList.forEach((bean) {
      if (bean.title == coinName) {
        if (transferType == "0") {
          bean.num = (double.parse(bean.num) - double.parse(upDown)).toString();
          bean.cnyMoney =
              (double.parse(bean.cnyMoney) - double.parse(costCnyMoney))
                  .toString();
        } else {
          bean.num = (double.parse(bean.num) + double.parse(upDown)).toString();
          bean.cnyMoney =
              (double.parse(bean.cnyMoney) + double.parse(costCnyMoney))
                  .toString();
        }
      }
    });

    SpUtil.putString(Constant.allCoinListKey, json.encode(coinList).toString());
    SpUtil.putString(
        Constant.selectCoinListKey, json.encode(coinSelectList).toString());
  }

  CoinsBean getSingleCoinDetailModel(String coinName) {
    if (coinName.isEmpty) return null;
    CoinsBean bean = CoinsBean();
    List<CoinsBean> coinList = getCoinList(false);
    coinList.forEach((coin) {
      if (coin.title == coinName) {
        bean = coin;
      }
    });
    return bean;
  }

  num getTotalAssetsCNY() {
    List<CoinsBean> coinList = getCoinList(false);
    num totalAssets = 0.0;
    coinList.forEach((coin) {
      totalAssets += NumUtil.getNumByValueStr(coin.cnyMoney, fractionDigits: 8);
    });
    return totalAssets;
  }
}
